<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>面试官问：能否模拟实现JS的call和apply方法 | 若川的博客</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/favicon.ico">
    <link rel="mainfest" href="/mainfest.json">
    <meta name="description" content="若川，微信搜索「若川视野」关注我，长期交流学习。写有《学习源码整体架构系列》。包含jquery源码、underscore源码、lodash源码、sentry源码、vuex源码、axios源码、koa源码、redux源码。前端路上，PPT爱好者，所知甚少，唯善学。">
    
    <link rel="preload" href="/assets/css/0.styles.0ad39d54.css" as="style"><link rel="preload" href="/assets/js/app.9fbcafa6.js" as="script"><link rel="preload" href="/assets/js/2.33539d56.js" as="script"><link rel="preload" href="/assets/js/36.21f88fe5.js" as="script"><link rel="preload" href="/assets/js/23.72249401.js" as="script"><link rel="prefetch" href="/assets/js/10.17a947d6.js"><link rel="prefetch" href="/assets/js/11.599e7eee.js"><link rel="prefetch" href="/assets/js/12.574e6f26.js"><link rel="prefetch" href="/assets/js/13.3a93edbc.js"><link rel="prefetch" href="/assets/js/14.c9f20b6b.js"><link rel="prefetch" href="/assets/js/15.c6b03e37.js"><link rel="prefetch" href="/assets/js/16.c445ccb9.js"><link rel="prefetch" href="/assets/js/17.60b94fab.js"><link rel="prefetch" href="/assets/js/18.86de3f95.js"><link rel="prefetch" href="/assets/js/19.6fedd448.js"><link rel="prefetch" href="/assets/js/20.5b11fd5b.js"><link rel="prefetch" href="/assets/js/21.e5faf0b7.js"><link rel="prefetch" href="/assets/js/22.23137eae.js"><link rel="prefetch" href="/assets/js/24.20d474b3.js"><link rel="prefetch" href="/assets/js/25.6dc03c07.js"><link rel="prefetch" href="/assets/js/26.fcf5232b.js"><link rel="prefetch" href="/assets/js/27.6ee352c4.js"><link rel="prefetch" href="/assets/js/28.7534ba1e.js"><link rel="prefetch" href="/assets/js/29.352ed61c.js"><link rel="prefetch" href="/assets/js/3.2f315ac7.js"><link rel="prefetch" href="/assets/js/30.e5dbb079.js"><link rel="prefetch" href="/assets/js/31.b8562982.js"><link rel="prefetch" href="/assets/js/32.f3c8f832.js"><link rel="prefetch" href="/assets/js/33.5ca5188e.js"><link rel="prefetch" href="/assets/js/34.624e3116.js"><link rel="prefetch" href="/assets/js/35.35a86a7c.js"><link rel="prefetch" href="/assets/js/37.f5b01c2c.js"><link rel="prefetch" href="/assets/js/38.79ed2093.js"><link rel="prefetch" href="/assets/js/39.687f8425.js"><link rel="prefetch" href="/assets/js/4.9af06e45.js"><link rel="prefetch" href="/assets/js/40.deaa2213.js"><link rel="prefetch" href="/assets/js/41.ede9f8e5.js"><link rel="prefetch" href="/assets/js/42.c48ff846.js"><link rel="prefetch" href="/assets/js/43.012e8b81.js"><link rel="prefetch" href="/assets/js/44.d7040c40.js"><link rel="prefetch" href="/assets/js/45.2805a83b.js"><link rel="prefetch" href="/assets/js/46.95a37284.js"><link rel="prefetch" href="/assets/js/47.d1c213db.js"><link rel="prefetch" href="/assets/js/48.00be6d02.js"><link rel="prefetch" href="/assets/js/49.3d722bd1.js"><link rel="prefetch" href="/assets/js/5.aace9ee0.js"><link rel="prefetch" href="/assets/js/50.d9fa2cde.js"><link rel="prefetch" href="/assets/js/51.e0aaa97a.js"><link rel="prefetch" href="/assets/js/52.a700a7a9.js"><link rel="prefetch" href="/assets/js/53.dbb93ca1.js"><link rel="prefetch" href="/assets/js/6.e0576ee1.js"><link rel="prefetch" href="/assets/js/7.4a4a967d.js"><link rel="prefetch" href="/assets/js/8.b7698a4a.js"><link rel="prefetch" href="/assets/js/9.6930a420.js">
    <link rel="stylesheet" href="/assets/css/0.styles.0ad39d54.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">若川的博客</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="https://image-static.segmentfault.com/355/182/3551821948-5df888aa1dc88_articlex" target="_blank" rel="noopener noreferrer" class="nav-link external">
  公众号：若川视野
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="/" class="nav-link">
  目录
</a></div><div class="nav-item"><a href="/about/" class="nav-link">
  关于我
</a></div><div class="nav-item"><a href="/poetry/2012-2016/" class="nav-link">
  曾经写的&quot;诗词&quot;
</a></div><div class="nav-item"><a href="https://github.com/lxchuan12/blog" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://juejin.im/user/1415826704971918/posts" target="_blank" rel="noopener noreferrer" class="nav-link external">
  掘金
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://www.zhihu.com/people/lxchuan12/activities" target="_blank" rel="noopener noreferrer" class="nav-link external">
  知乎
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://www.yuque.com/lxchuan12/blog" target="_blank" rel="noopener noreferrer" class="nav-link external">
  语雀
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="其他" class="dropdown-title"><span class="title">其他</span> <span class="arrow down"></span></button> <button type="button" aria-label="其他" class="mobile-dropdown-title"><span class="title">其他</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://segmentfault.com/u/lxchuan12/articles" target="_blank" rel="noopener noreferrer" class="nav-link external">
  segmentFault
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://weibo.com/lxchuan12" target="_blank" rel="noopener noreferrer" class="nav-link external">
  微博
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://www.jianshu.com/users/83129d433d72/latest_articles" target="_blank" rel="noopener noreferrer" class="nav-link external">
  简书
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="友链" class="dropdown-title"><span class="title">友链</span> <span class="arrow down"></span></button> <button type="button" aria-label="友链" class="mobile-dropdown-title"><span class="title">友链</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://shanyue.tech" target="_blank" rel="noopener noreferrer" class="nav-link external">
  山月
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://lucifer.ren" target="_blank" rel="noopener noreferrer" class="nav-link external">
  lucifer
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://hungryturbo.com" target="_blank" rel="noopener noreferrer" class="nav-link external">
  童欧巴
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://www.scarsu.com/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  scarsu
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://mtc.nofwl.com/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  lencx的博客
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://coder.itclan.cn/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  itclanCoder
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://ruizhengyun.cn" target="_blank" rel="noopener noreferrer" class="nav-link external">
  编程之上
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="https://image-static.segmentfault.com/355/182/3551821948-5df888aa1dc88_articlex" target="_blank" rel="noopener noreferrer" class="nav-link external">
  公众号：若川视野
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="/" class="nav-link">
  目录
</a></div><div class="nav-item"><a href="/about/" class="nav-link">
  关于我
</a></div><div class="nav-item"><a href="/poetry/2012-2016/" class="nav-link">
  曾经写的&quot;诗词&quot;
</a></div><div class="nav-item"><a href="https://github.com/lxchuan12/blog" target="_blank" rel="noopener noreferrer" class="nav-link external">
  Github
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://juejin.im/user/1415826704971918/posts" target="_blank" rel="noopener noreferrer" class="nav-link external">
  掘金
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://www.zhihu.com/people/lxchuan12/activities" target="_blank" rel="noopener noreferrer" class="nav-link external">
  知乎
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><a href="https://www.yuque.com/lxchuan12/blog" target="_blank" rel="noopener noreferrer" class="nav-link external">
  语雀
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="其他" class="dropdown-title"><span class="title">其他</span> <span class="arrow down"></span></button> <button type="button" aria-label="其他" class="mobile-dropdown-title"><span class="title">其他</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://segmentfault.com/u/lxchuan12/articles" target="_blank" rel="noopener noreferrer" class="nav-link external">
  segmentFault
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://weibo.com/lxchuan12" target="_blank" rel="noopener noreferrer" class="nav-link external">
  微博
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://www.jianshu.com/users/83129d433d72/latest_articles" target="_blank" rel="noopener noreferrer" class="nav-link external">
  简书
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="友链" class="dropdown-title"><span class="title">友链</span> <span class="arrow down"></span></button> <button type="button" aria-label="友链" class="mobile-dropdown-title"><span class="title">友链</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="https://shanyue.tech" target="_blank" rel="noopener noreferrer" class="nav-link external">
  山月
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="http://lucifer.ren" target="_blank" rel="noopener noreferrer" class="nav-link external">
  lucifer
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://hungryturbo.com" target="_blank" rel="noopener noreferrer" class="nav-link external">
  童欧巴
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://www.scarsu.com/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  scarsu
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://mtc.nofwl.com/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  lencx的博客
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://coder.itclan.cn/" target="_blank" rel="noopener noreferrer" class="nav-link external">
  itclanCoder
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-item"><!----> <a href="https://ruizhengyun.cn" target="_blank" rel="noopener noreferrer" class="nav-link external">
  编程之上
  <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></div></div> <!----></nav>  <ul class="sidebar-links"><li><a href="/" aria-current="page" class="sidebar-link">目录</a></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>学习源码系列</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>面试官问系列</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/js-extend/" class="sidebar-link">面试官问：JS的继承</a></li><li><a href="/js-this/" class="sidebar-link">面试官问：JS的this指向</a></li><li><a href="/js-implement-call-apply/" aria-current="page" class="active sidebar-link">面试官问：能否模拟实现JS的call和apply方法</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#前言" class="sidebar-link">前言</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#先通过mdn认识下call和apply" class="sidebar-link">先通过MDN认识下call和apply</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#call-和-apply-的异同" class="sidebar-link">call 和 apply 的异同</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#模拟实现-apply" class="sidebar-link">模拟实现 apply</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#实现第一版后-很容易找出两个问题" class="sidebar-link">实现第一版后，很容易找出两个问题：</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#你可能不知道在es3、es5中-undefined-是能修改的" class="sidebar-link">你可能不知道在ES3、ES5中 undefined 是能修改的</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#使用-new-function-模拟实现的apply" class="sidebar-link">使用 new Function() 模拟实现的apply</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#利用模拟实现的apply模拟实现call" class="sidebar-link">利用模拟实现的apply模拟实现call</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#总结" class="sidebar-link">总结</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#扩展阅读" class="sidebar-link">扩展阅读</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#关于" class="sidebar-link">关于</a></li><li class="sidebar-sub-header"><a href="/js-implement-call-apply/#微信公众号-若川视野" class="sidebar-link">微信公众号  若川视野</a></li></ul></li><li><a href="/js-implement-bind/" class="sidebar-link">面试官问：能否模拟实现JS的bind方法</a></li><li><a href="/js-implement-new/" class="sidebar-link">面试官问：能否模拟实现JS的new操作符</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>历史文章</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>杂文</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>曾经写的&quot;诗词&quot;</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>年度总结</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>关于</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="面试官问-能否模拟实现js的call和apply方法"><a href="#面试官问-能否模拟实现js的call和apply方法" class="header-anchor">#</a> 面试官问：能否模拟实现JS的call和apply方法</h1> <blockquote><p><code>写于2018年11月30日</code></p></blockquote> <h2 id="前言"><a href="#前言" class="header-anchor">#</a> 前言</h2> <blockquote><p>你好，我是<a href="https://lxchuan12.gitee.io" target="_blank" rel="noopener noreferrer">若川<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，微信搜索<a href="https://mp.weixin.qq.com/s/c3hFML3XN9KCUetDOZd-DQ" target="_blank" rel="noopener noreferrer">「若川视野」<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>关注我，专注前端技术分享。欢迎加我微信<code>ruochuan12</code>，加群交流学习。</p></blockquote> <blockquote><p>这是面试官问系列的第三篇，旨在帮助读者提升<code>JS</code>基础知识，包含<code>new、call、apply、this、继承</code>相关知识。<br> <code>面试官问系列</code>文章如下：感兴趣的读者可以点击阅读。<br>
1.<a href="https://juejin.im/post/5bde7c926fb9a049f66b8b52" target="_blank" rel="noopener noreferrer">面试官问：能否模拟实现JS的new操作符<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br>
2.<a href="https://juejin.im/post/5bec4183f265da616b1044d7" target="_blank" rel="noopener noreferrer">面试官问：能否模拟实现JS的bind方法<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br>
3.<a href="https://juejin.im/post/5bf6c79bf265da6142738b29" target="_blank" rel="noopener noreferrer">面试官问：能否模拟实现JS的call和apply方法<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br>
4.<a href="https://juejin.im/post/5c0c87b35188252e8966c78a" target="_blank" rel="noopener noreferrer">面试官问：JS的this指向<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br>
5.<a href="https://juejin.im/post/5c433e216fb9a049c15f841b" target="_blank" rel="noopener noreferrer">面试官问：JS的继承<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br></p></blockquote> <p>之前写过两篇<a href="https://juejin.im/post/5bde7c926fb9a049f66b8b52" target="_blank" rel="noopener noreferrer">《面试官问：能否模拟实现<code>JS</code>的<code>new</code>操作符》<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>和<a href="https://juejin.im/post/5bec4183f265da616b1044d7" target="_blank" rel="noopener noreferrer">《面试官问：能否模拟实现<code>JS</code>的<code>bind</code>方法》<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p>其中模拟<code>bind</code>方法时是使用的<code>call</code>和<code>apply</code>修改<code>this</code>指向。但面试官可能问：能否不用<code>call</code>和<code>apply</code>来实现呢。意思也就是需要模拟实现<code>call</code>和<code>apply</code>的了。</p> <blockquote><p>附上之前写文章写过的一段话：已经有很多模拟实现<code>call</code>和<code>apply</code>的文章，为什么自己还要写一遍呢。学习就好比是座大山，人们沿着不同的路登山，分享着自己看到的风景。你不一定能看到别人看到的风景，体会到别人的心情。只有自己去登山，才能看到不一样的风景，体会才更加深刻。<br></p></blockquote> <h2 id="先通过mdn认识下call和apply"><a href="#先通过mdn认识下call和apply" class="header-anchor">#</a> 先通过<code>MDN</code>认识下<code>call</code>和<code>apply</code></h2> <p><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/call" target="_blank" rel="noopener noreferrer">MDN 文档：Function.prototype.call()<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br> <strong>语法</strong><br></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">fun</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">,</span> arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>thisArg</strong><br>
在<code>fun</code>函数运行时指定的<code>this</code>值。需要注意的是，指定的<code>this</code>值并不一定是该函数执行时真正的<code>this</code>值，如果这个函数处于<strong>非严格模式</strong>下，则指定为<code>null</code>和<code>undefined</code>的<code>this</code>值会自动指向全局对象(浏览器中就是<code>window</code>对象)，同时值为原始值(数字，字符串，布尔值)的<code>this</code>会指向该原始值的自动包装对象。<br> <strong>arg1, arg2, ...</strong><br>
指定的参数列表<br> <strong>返回值</strong><br>
返回值是你调用的方法的返回值，若该方法没有返回值，则返回<code>undefined</code>。<br></p> <p><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply" target="_blank" rel="noopener noreferrer">MDN 文档：Function.prototype.apply()<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">func</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">,</span> <span class="token punctuation">[</span>argsArray<span class="token punctuation">]</span><span class="token punctuation">)</span>
</code></pre></div><p><strong>thisArg</strong><br>
可选的。在 <code>func</code> 函数运行时使用的 <code>this</code> 值。请注意，<code>this</code>可能不是该方法看到的实际值：如果这个函数处于<strong>非严格模式</strong>下，则指定为 <code>null</code> 或 <code>undefined</code> 时会自动替换为指向全局对象，原始值会被包装。<br> <strong>argsArray</strong><br>
可选的。一个数组或者类数组对象，其中的数组元素将作为单独的参数传给 <code>func</code> 函数。如果该参数的值为 <code>null</code> 或  <code>undefined</code>，则表示不需要传入任何参数。从<code>ECMAScript 5</code> 开始可以使用类数组对象。<br> <strong>返回值</strong><br>
调用有指定this值和参数的函数的结果。
直接先看<strong>例子1</strong></p> <h2 id="call-和-apply-的异同"><a href="#call-和-apply-的异同" class="header-anchor">#</a> <code>call</code> 和 <code>apply</code> 的异同</h2> <p><strong>相同点：</strong><br>
1、<code>call</code>和<code>apply</code>的第一个参数<code>thisArg</code>，都是<code>func</code>运行时指定的<code>this</code>。而且，<code>this</code>可能不是该方法看到的实际值：如果这个函数处于<strong>非严格模式</strong>下，则指定为 <code>null</code> 或 <code>undefined</code> 时会自动替换为指向全局对象，原始值会被包装。<br>
2、都可以只传递一个参数。<br> <strong>不同点：</strong><code>apply</code>只接收两个参数，第二个参数可以是数组也可以是类数组，其实也可以是对象，后续的参数忽略不计。<code>call</code>接收第二个及以后一系列的参数。<br>
看两个简单例子1和2**：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 例子1：浏览器环境 非严格模式下</span>
<span class="token keyword">var</span> <span class="token function-variable function">doSth</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">doSth</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this是window  // [1, 2]</span>
<span class="token function">doSth</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this 是 Number(0) // [1, 2]</span>
<span class="token function">doSth</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this 是 Boolean(true) // [undefined, undefined]</span>
<span class="token function">doSth</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this 是 window // [1, 2]</span>
<span class="token function">doSth</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token string">'0'</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>a<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this 是 String('0') // [1, {a: 1}]</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 例子2：浏览器环境 严格模式下</span>
<span class="token string">'use strict'</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> <span class="token function-variable function">doSth2</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token function">doSth2</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this 是 0 // [1, 2]</span>
<span class="token function">doSth2</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token string">'1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this 是 '1' // [undefined, undefined]</span>
<span class="token function">doSth2</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span><span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this 是 null // [1, 2]</span>
</code></pre></div><p><code>typeof</code> 有<code>7</code>种类型（<code>undefined number string boolean symbol object function</code>），笔者都验证了一遍：<strong>更加验证了相同点第一点，严格模式下，函数的<code>this</code>值就是<code>call</code>和<code>apply</code>的第一个参数<code>thisArg</code>，非严格模式下，<code>thisArg</code>值被指定为 <code>null</code> 或 <code>undefined</code> 时<code>this</code>值会自动替换为指向全局对象，原始值则会被自动包装，也就是<code>new Object()</code></strong>。</p> <p>重新认识了<code>call</code>和<code>apply</code>会发现：<strong>它们作用都是一样的，改变函数里的<code>this</code>指向为第一个参数<code>thisArg</code>，如果明确有多少参数，那可以用<code>call</code>，不明确则可以使用<code>apply</code>。也就是说完全可以不使用<code>call</code>，而使用<code>apply</code>代替。</strong><br>
也就是说，我们只需要模拟实现<code>apply</code>，<code>call</code>可以根据参数个数都放在一个数组中，给到<code>apply</code>即可。<br></p> <h2 id="模拟实现-apply"><a href="#模拟实现-apply" class="header-anchor">#</a> 模拟实现 <code>apply</code></h2> <p>既然准备模拟实现<code>apply</code>，那先得看看<code>ES5</code>规范。<a href="http://es5.github.io/#x15.3.4.3" target="_blank" rel="noopener noreferrer"><code>ES5规范 英文版</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，<a href="http://yanhaijing.com/es5/#322" target="_blank" rel="noopener noreferrer"><code>ES5规范 中文版</code><span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>。<code>apply</code>的规范下一个就是<code>call</code>的规范，可以点击打开新标签页去查看，这里摘抄一部分。</p> <blockquote><p><strong>Function.prototype.apply (thisArg, argArray)</strong><br>
当以 <code>thisArg</code> 和 <code>argArray</code> 为参数在一个 <code>func</code> 对象上调用 <code>apply</code> 方法，采用如下步骤：</p></blockquote> <blockquote><p>1.如果 <code>IsCallable(func)</code> 是 <code>false</code>, 则抛出一个 <code>TypeError</code> 异常。<br>
2.如果 <code>argArray</code> 是 <code>null</code> 或 <code>undefined</code>, 则返回提供 <code>thisArg</code> 作为 <code>this</code> 值并以空参数列表调用 <code>func</code> 的 <code>[[Call]]</code> 内部方法的结果。<br>
3.返回提供 <code>thisArg</code> 作为 <code>this</code> 值并以空参数列表调用 <code>func</code> 的 <code>[[Call]]</code> 内部方法的结果。<br>
4.如果 <code>Type(argArray)</code> 不是 <code>Object</code>, 则抛出一个 <code>TypeError</code> 异常。<br>
5~8 略<br>
9.提供 <code>thisArg</code> 作为 <code>this</code> 值并以 <code>argList</code> 作为参数列表，调用 <code>func</code> 的 <code>[[Call]]</code> 内部方法，返回结果。<br> <code>apply</code> 方法的 <code>length</code> 属性是 <code>2</code>。<br></p></blockquote> <blockquote><p>在外面传入的 <code>thisArg</code> 值会修改并成为 <code>this</code> 值。<code>thisArg</code> 是 <code>undefined</code> 或 <code>null</code> 时它会被替换成全局对象，所有其他值会被应用 <code>ToObject</code> 并将结果作为 <code>this</code> 值，这是第三版引入的更改。<br></p></blockquote> <p>结合上文和规范，如何将函数里的<code>this</code>指向第一个参数<code>thisArg</code>呢，这是一个问题。
这时候请出<strong>例子3</strong>：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 浏览器环境 非严格模式下</span>
<span class="token keyword">var</span> <span class="token function-variable function">doSth</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">a<span class="token punctuation">,</span> b</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token punctuation">[</span>a<span class="token punctuation">,</span> b<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">var</span> student <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">'若川'</span><span class="token punctuation">,</span>
    doSth<span class="token operator">:</span> doSth<span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
student<span class="token punctuation">.</span><span class="token function">doSth</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this === student // true // '若川' // [1, 2]</span>
<span class="token function">doSth</span><span class="token punctuation">.</span><span class="token function">apply</span><span class="token punctuation">(</span>student<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// this === student // true // '若川' // [1, 2]</span>
</code></pre></div><p>可以<strong>得出结论1</strong>：在对象<code>student</code>上加一个函数<code>doSth</code>，再执行这个函数，这个函数里的<code>this</code>就指向了这个对象。那也就是可以在<code>thisArg</code>上新增调用函数，执行后删除这个函数即可。
知道这些后，我们试着容易实现第一版本：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 浏览器环境 非严格模式</span>
<span class="token keyword">function</span> <span class="token function">getGlobalObject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">applyFn</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">apply</span><span class="token punctuation">(</span><span class="token parameter">thisArg<span class="token punctuation">,</span> argsArray</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// `apply` 方法的 `length` 属性是 `2`。</span>
    <span class="token comment">// 1.如果 `IsCallable(func)` 是 `false`, 则抛出一个 `TypeError` 异常。</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> <span class="token keyword">this</span> <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">+</span> <span class="token string">' is not a function'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// 2.如果 argArray 是 null 或 undefined, 则</span>
    <span class="token comment">// 返回提供 thisArg 作为 this 值并以空参数列表调用 func 的 [[Call]] 内部方法的结果。</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> argsArray <span class="token operator">===</span> <span class="token string">'undefined'</span> <span class="token operator">||</span> argsArray <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        argsArray <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// 3.如果 Type(argArray) 不是 Object, 则抛出一个 TypeError 异常 .</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>argsArray <span class="token operator">!==</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span>argsArray<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">'CreateListFromArrayLike called on non-object'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> thisArg <span class="token operator">===</span> <span class="token string">'undefined'</span> <span class="token operator">||</span> thisArg <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token comment">// 在外面传入的 thisArg 值会修改并成为 this 值。</span>
        <span class="token comment">// ES3: thisArg 是 undefined 或 null 时它会被替换成全局对象 浏览器里是window</span>
        thisArg <span class="token operator">=</span> <span class="token function">getGlobalObject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ES3: 所有其他值会被应用 ToObject 并将结果作为 this 值，这是第三版引入的更改。</span>
    thisArg <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> __fn <span class="token operator">=</span> <span class="token string">'__fn'</span><span class="token punctuation">;</span>
    thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
    <span class="token comment">// 9.提供 thisArg 作为 this 值并以 argList 作为参数列表，调用 func 的 [[Call]] 内部方法，返回结果</span>
    <span class="token keyword">var</span> result <span class="token operator">=</span> thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span><span class="token punctuation">(</span><span class="token operator">...</span>argsArray<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">delete</span> thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="实现第一版后-很容易找出两个问题"><a href="#实现第一版后-很容易找出两个问题" class="header-anchor">#</a> 实现第一版后，很容易找出两个问题：</h2> <ul><li>[ ] 1.<code>__fn</code> 同名覆盖问题，<code>thisArg</code>对象上有<code>__fn</code>，那就被覆盖了然后被删除了。</li></ul> <p><strong>针对问题1</strong>
解决方案一：采用<code>ES6</code> <code>Sybmol()</code> 独一无二的。可以本来就是模拟<code>ES3</code>的方法。如果面试官不允许用呢。
解决方案二：自己用<code>Math.random()</code>模拟实现独一无二的<code>key</code>。面试时可以直接用生成时间戳即可。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 生成UUID 通用唯一识别码</span>
<span class="token comment">// 大概生成 这样一串 '18efca2d-6e25-42bf-a636-30b8f9f2de09'</span>
<span class="token keyword">function</span> <span class="token function">generateUUID</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">var</span> i<span class="token punctuation">,</span> random<span class="token punctuation">;</span>
    <span class="token keyword">var</span> uuid <span class="token operator">=</span> <span class="token string">''</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> <span class="token number">32</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        random <span class="token operator">=</span> Math<span class="token punctuation">.</span><span class="token function">random</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">16</span> <span class="token operator">|</span> <span class="token number">0</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">8</span> <span class="token operator">||</span> i <span class="token operator">===</span> <span class="token number">12</span> <span class="token operator">||</span> i <span class="token operator">===</span> <span class="token number">16</span> <span class="token operator">||</span> i <span class="token operator">===</span> <span class="token number">20</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            uuid <span class="token operator">+=</span> <span class="token string">'-'</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        uuid <span class="token operator">+=</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">12</span> <span class="token operator">?</span> <span class="token number">4</span> <span class="token operator">:</span> <span class="token punctuation">(</span>i <span class="token operator">===</span> <span class="token number">16</span> <span class="token operator">?</span> <span class="token punctuation">(</span>random <span class="token operator">&amp;</span> <span class="token number">3</span> <span class="token operator">|</span> <span class="token number">8</span><span class="token punctuation">)</span> <span class="token operator">:</span> random<span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> uuid<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 简单实现</span>
<span class="token comment">// '__' + new Date().getTime();</span>
</code></pre></div><p>如果这个<code>key</code>万一这对象中还是有，为了保险起见，可以做一次缓存操作。比如如下代码：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> student <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">'若川'</span><span class="token punctuation">,</span>
    doSth<span class="token operator">:</span> <span class="token string">'doSth'</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> originalVal <span class="token operator">=</span> student<span class="token punctuation">.</span>doSth<span class="token punctuation">;</span>
<span class="token keyword">var</span> hasOriginalVal <span class="token operator">=</span> student<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span><span class="token string">'doSth'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
student<span class="token punctuation">.</span><span class="token function-variable function">doSth</span> <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">delete</span> student<span class="token punctuation">.</span>doSth<span class="token punctuation">;</span>
<span class="token comment">// 如果没有，`originalVal`则为undefined，直接赋值新增了一个undefined，这是不对的，所以需判断一下。</span>
<span class="token keyword">if</span><span class="token punctuation">(</span>hasOriginalVal<span class="token punctuation">)</span><span class="token punctuation">{</span>
    student<span class="token punctuation">.</span>doSth <span class="token operator">=</span> originalVal<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'student:'</span><span class="token punctuation">,</span> student<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// { name: '若川', doSth: 'doSth' }</span>
</code></pre></div><ul><li>[ ] 2.使用了<code>ES6</code>扩展符<code>...</code><br>
解决方案一：采用<code>eval</code>来执行函数。<br></li></ul> <blockquote><p><code>eval</code>把字符串解析成代码执行。<br> <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval" target="_blank" rel="noopener noreferrer">MDN 文档：eval<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br> <strong>语法</strong></p></blockquote> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">eval</span><span class="token punctuation">(</span>string<span class="token punctuation">)</span>
</code></pre></div><p><strong>参数</strong><br> <strong>string</strong><br>
表示<code>JavaScript</code>表达式，语句或一系列语句的字符串。表达式可以包含变量以及已存在对象的属性。<br> <strong>返回值</strong><br>
执行指定代码之后的返回值。如果返回值为空，返回<code>undefined</code><br>
解决方案二：但万一面试官不允许用<code>eval</code>呢，毕竟<code>eval</code>是魔鬼。可以采用<code>new Function()</code>来生成执行函数。
<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function" target="_blank" rel="noopener noreferrer">MDN 文档：Function<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br> <strong>语法</strong><br></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">new</span> <span class="token class-name">Function</span> <span class="token punctuation">(</span><span class="token punctuation">[</span>arg1<span class="token punctuation">[</span><span class="token punctuation">,</span> arg2<span class="token punctuation">[</span><span class="token punctuation">,</span> <span class="token operator">...</span>argN<span class="token punctuation">]</span><span class="token punctuation">]</span><span class="token punctuation">,</span><span class="token punctuation">]</span> functionBody<span class="token punctuation">)</span>
</code></pre></div><p><strong>参数</strong><br> <strong>arg1, arg2, ... argN</strong><br>
被函数使用的参数的名称必须是合法命名的。参数名称是一个有效的<code>JavaScript</code>标识符的字符串，或者一个用逗号分隔的有效字符串的列表;例如<code>“×”</code>，<code>“theValue”</code>，或<code>“A，B”</code>。<br> <strong>functionBody</strong><br>
一个含有包括函数定义的<code>JavaScript</code>语句的字符串。<br>
接下来看两个例子：</p> <div class="language-js extra-class"><pre class="language-js"><code>简单例子：
<span class="token keyword">var</span> sum <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">'a'</span><span class="token punctuation">,</span> <span class="token string">'b'</span><span class="token punctuation">,</span> <span class="token string">'return a + b'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token function">sum</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">6</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 稍微复杂点的例子：</span>
<span class="token keyword">var</span> student <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">'若川'</span><span class="token punctuation">,</span>
    <span class="token function-variable function">doSth</span><span class="token operator">:</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token parameter">argsArray</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>argsArray<span class="token punctuation">)</span><span class="token punctuation">;</span>
        console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// var result = student.doSth(['若川i', 18]);</span>
<span class="token comment">// 用new Function()生成函数并执行返回结果</span>
<span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span><span class="token string">'return arguments[0][arguments[1]](arguments[2][0], arguments[2][1])'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>student<span class="token punctuation">,</span> <span class="token string">'doSth'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'若川i'</span><span class="token punctuation">,</span> <span class="token number">18</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// 个数不定</span>
<span class="token comment">// 所以可以写一个函数生成函数代码：</span>
<span class="token keyword">function</span> <span class="token function">generateFunctionCode</span><span class="token punctuation">(</span><span class="token parameter">argsArrayLength</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">var</span> code <span class="token operator">=</span> <span class="token string">'return arguments[0][arguments[1]]('</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> argsArrayLength<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>i <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            code <span class="token operator">+=</span> <span class="token string">','</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        code <span class="token operator">+=</span> <span class="token string">'arguments[2]['</span> <span class="token operator">+</span> i <span class="token operator">+</span> <span class="token string">']'</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    code <span class="token operator">+=</span> <span class="token string">')'</span><span class="token punctuation">;</span>
    <span class="token comment">// return arguments[0][arguments[1]](arg1, arg2, arg3...)</span>
    <span class="token keyword">return</span> code<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="你可能不知道在es3、es5中-undefined-是能修改的"><a href="#你可能不知道在es3、es5中-undefined-是能修改的" class="header-anchor">#</a> 你可能不知道在<code>ES3、ES5</code>中 <code>undefined</code> 是能修改的</h2> <p>可能大部分人不知道。<code>ES5</code>中虽然在全局作用域下不能修改，但在局部作用域中也是能修改的，不信可以复制以下测试代码在控制台执行下。虽然一般情况下是不会的去修改它。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">var</span> <span class="token keyword">undefined</span> <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">undefined</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// chrome下也是 3</span>
<span class="token punctuation">}</span>
<span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>所以判断一个变量<code>a</code>是不是<code>undefined</code>，更严谨的方案是<code>typeof a === 'undefined'</code>或者<code>a === void 0;</code>
这里面用的是<code>void</code>，<code>void</code>的作用是计算表达式，始终返回<code>undefined</code>，也可以这样写<code>void(0)</code>。
更多可以查看<code>韩子迟</code>的这篇文章：<a href="https://github.com/hanzichi/underscore-analysis/issues/1" target="_blank" rel="noopener noreferrer">为什么用「void 0」代替「undefined」<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>
解决了这几个问题，比较容易实现如下代码。</p> <h2 id="使用-new-function-模拟实现的apply"><a href="#使用-new-function-模拟实现的apply" class="header-anchor">#</a> 使用 <code>new Function()</code> 模拟实现的<code>apply</code></h2> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 浏览器环境 非严格模式</span>
<span class="token keyword">function</span> <span class="token function">getGlobalObject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">generateFunctionCode</span><span class="token punctuation">(</span><span class="token parameter">argsArrayLength</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">var</span> code <span class="token operator">=</span> <span class="token string">'return arguments[0][arguments[1]]('</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> argsArrayLength<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>i <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            code <span class="token operator">+=</span> <span class="token string">','</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        code <span class="token operator">+=</span> <span class="token string">'arguments[2]['</span> <span class="token operator">+</span> i <span class="token operator">+</span> <span class="token string">']'</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    code <span class="token operator">+=</span> <span class="token string">')'</span><span class="token punctuation">;</span>
    <span class="token comment">// return arguments[0][arguments[1]](arg1, arg2, arg3...)</span>
    <span class="token keyword">return</span> code<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">applyFn</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">apply</span><span class="token punctuation">(</span><span class="token parameter">thisArg<span class="token punctuation">,</span> argsArray</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment">// `apply` 方法的 `length` 属性是 `2`。</span>
    <span class="token comment">// 1.如果 `IsCallable(func)` 是 `false`, 则抛出一个 `TypeError` 异常。</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> <span class="token keyword">this</span> <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">+</span> <span class="token string">' is not a function'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">// 2.如果 argArray 是 null 或 undefined, 则</span>
    <span class="token comment">// 返回提供 thisArg 作为 this 值并以空参数列表调用 func 的 [[Call]] 内部方法的结果。</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> argsArray <span class="token operator">===</span> <span class="token string">'undefined'</span> <span class="token operator">||</span> argsArray <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        argsArray <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">// 3.如果 Type(argArray) 不是 Object, 则抛出一个 TypeError 异常 .</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>argsArray <span class="token operator">!==</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span>argsArray<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">'CreateListFromArrayLike called on non-object'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> thisArg <span class="token operator">===</span> <span class="token string">'undefined'</span> <span class="token operator">||</span> thisArg <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token comment">// 在外面传入的 thisArg 值会修改并成为 this 值。</span>
        <span class="token comment">// ES3: thisArg 是 undefined 或 null 时它会被替换成全局对象 浏览器里是window</span>
        thisArg <span class="token operator">=</span> <span class="token function">getGlobalObject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token comment">// ES3: 所有其他值会被应用 ToObject 并将结果作为 this 值，这是第三版引入的更改。</span>
    thisArg <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> __fn <span class="token operator">=</span> <span class="token string">'__'</span> <span class="token operator">+</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">// 万一还是有 先存储一份，删除后，再恢复该值</span>
    <span class="token keyword">var</span> originalVal <span class="token operator">=</span> thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token comment">// 是否有原始值</span>
    <span class="token keyword">var</span> hasOriginalVal <span class="token operator">=</span> thisArg<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>__fn<span class="token punctuation">)</span><span class="token punctuation">;</span>
    thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
    <span class="token comment">// 9.提供 `thisArg` 作为 `this` 值并以 `argList` 作为参数列表，调用 `func` 的 `[[Call]]` 内部方法，返回结果。</span>
    <span class="token comment">// ES6版</span>
    <span class="token comment">// var result = thisArg[__fn](...args);</span>
    <span class="token keyword">var</span> code <span class="token operator">=</span> <span class="token function">generateFunctionCode</span><span class="token punctuation">(</span>argsArray<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span>code<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">,</span> __fn<span class="token punctuation">,</span> argsArray<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">delete</span> thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>hasOriginalVal<span class="token punctuation">)</span><span class="token punctuation">{</span>
        thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span> <span class="token operator">=</span> originalVal<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="利用模拟实现的apply模拟实现call"><a href="#利用模拟实现的apply模拟实现call" class="header-anchor">#</a> 利用模拟实现的<code>apply</code>模拟实现<code>call</code></h2> <div class="language-js extra-class"><pre class="language-js"><code><span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">callFn</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">call</span><span class="token punctuation">(</span><span class="token parameter">thisArg</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">var</span> argsArray <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> argumentsLength <span class="token operator">=</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> argumentsLength <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token comment">// argsArray.push(arguments[i + 1]);</span>
        argsArray<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> arguments<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'argsArray:'</span><span class="token punctuation">,</span> argsArray<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">applyFn</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">,</span> argsArray<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// 测试例子</span>
<span class="token keyword">var</span> <span class="token function-variable function">doSth</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">name<span class="token punctuation">,</span> age</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">var</span> type <span class="token operator">=</span> <span class="token class-name">Object</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">.</span><span class="token function">call</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> doSth<span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">===</span> firstArg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'type:'</span><span class="token punctuation">,</span> type<span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'this:'</span><span class="token punctuation">,</span> <span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'args:'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span>name<span class="token punctuation">,</span> age<span class="token punctuation">]</span><span class="token punctuation">,</span> arguments<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token string">'this--'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">var</span> name <span class="token operator">=</span> <span class="token string">'window'</span><span class="token punctuation">;</span>

<span class="token keyword">var</span> student <span class="token operator">=</span> <span class="token punctuation">{</span>
    name<span class="token operator">:</span> <span class="token string">'若川'</span><span class="token punctuation">,</span>
    age<span class="token operator">:</span> <span class="token number">18</span><span class="token punctuation">,</span>
    doSth<span class="token operator">:</span> <span class="token string">'doSth'</span><span class="token punctuation">,</span>
    __fn<span class="token operator">:</span> <span class="token string">'doSth'</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> firstArg <span class="token operator">=</span> student<span class="token punctuation">;</span>
<span class="token keyword">var</span> result <span class="token operator">=</span> doSth<span class="token punctuation">.</span><span class="token function">applyFn</span><span class="token punctuation">(</span>firstArg<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> <span class="token string">'若川i'</span><span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> result2 <span class="token operator">=</span> doSth<span class="token punctuation">.</span><span class="token function">callFn</span><span class="token punctuation">(</span>firstArg<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>name<span class="token operator">:</span> <span class="token string">'若川i'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'result:'</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'result2:'</span><span class="token punctuation">,</span> result2<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>细心的你会发现注释了这一句<code>argsArray.push(arguments[i + 1]);</code>，事实上<code>push</code>方法，内部也有一层循环。所以理论上不使用<code>push</code>性能会更好些。面试官也可能根据这点来问时间复杂度和空间复杂度的问题。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 看看V8引擎中的具体实现：</span>
<span class="token keyword">function</span> <span class="token function">ArrayPush</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">var</span> n <span class="token operator">=</span> <span class="token constant">TO_UINT32</span><span class="token punctuation">(</span> <span class="token keyword">this</span><span class="token punctuation">.</span>length <span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 被push的对象的length</span>
    <span class="token keyword">var</span> m <span class="token operator">=</span> <span class="token operator">%</span><span class="token function">_ArgumentsLength</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">// push的参数个数</span>
    <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> m<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">[</span> i <span class="token operator">+</span> n <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">%</span><span class="token function">_Arguments</span><span class="token punctuation">(</span> i <span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// 复制元素     (1)</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>length <span class="token operator">=</span> n <span class="token operator">+</span> m<span class="token punctuation">;</span>      <span class="token comment">// 修正length属性的值    (2)</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>length<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre></div><p>行文至此，就基本结束了，你可能还发现就是写的非严格模式下，<code>thisArg</code>原始值会包装成对象，添加函数并执行，再删除。而严格模式下还是原始值这个没有实现，而且万一这个对象是冻结对象呢，<code>Object.freeze({})</code>，是无法在这个对象上添加属性的。所以这个方法只能算是非严格模式下的简版实现。最后来总结一下。</p> <h2 id="总结"><a href="#总结" class="header-anchor">#</a> 总结</h2> <p>通过<code>MDN</code>认识<code>call</code>和<code>apply</code>，阅读<code>ES5</code>规范，到模拟实现<code>apply</code>，再实现<code>call</code>。<br>
就是使用在对象上添加调用<code>apply</code>的函数执行，这时的调用函数的<code>this</code>就指向了这个<code>thisArg</code>，再返回结果。引出了<code>ES6 Symbol</code>，<code>ES6</code>的扩展符<code>...</code>、<code>eval</code>、<code>new Function()</code>，严格模式等。<br>
事实上，现实业务场景不需要去模拟实现<code>call</code>和<code>apply</code>,毕竟是<code>ES3</code>就提供的方法。但面试官可以通过这个面试题考察候选人很多基础知识。如：<code>call</code>、<code>apply</code>的使用。<code>ES6 Symbol</code>，<code>ES6</code>的扩展符<code>...</code>，<code>eval</code>，<code>new Function()</code>，严格模式，甚至时间复杂度和空间复杂度等。<br>
读者发现有不妥或可改善之处，欢迎指出。另外觉得写得不错，可以点个赞，也是对笔者的一种支持。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// 最终版版 删除注释版，详细注释看文章</span>
<span class="token comment">// 浏览器环境 非严格模式</span>
<span class="token keyword">function</span> <span class="token function">getGlobalObject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">generateFunctionCode</span><span class="token punctuation">(</span><span class="token parameter">argsArrayLength</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">var</span> code <span class="token operator">=</span> <span class="token string">'return arguments[0][arguments[1]]('</span><span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> argsArrayLength<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>i <span class="token operator">&gt;</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
            code <span class="token operator">+=</span> <span class="token string">','</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        code <span class="token operator">+=</span> <span class="token string">'arguments[2]['</span> <span class="token operator">+</span> i <span class="token operator">+</span> <span class="token string">']'</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    code <span class="token operator">+=</span> <span class="token string">')'</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> code<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">applyFn</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">apply</span><span class="token punctuation">(</span><span class="token parameter">thisArg<span class="token punctuation">,</span> argsArray</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> <span class="token keyword">this</span> <span class="token operator">!==</span> <span class="token string">'function'</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token keyword">this</span> <span class="token operator">+</span> <span class="token string">' is not a function'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> argsArray <span class="token operator">===</span> <span class="token string">'undefined'</span> <span class="token operator">||</span> argsArray <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        argsArray <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>argsArray <span class="token operator">!==</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span>argsArray<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">TypeError</span><span class="token punctuation">(</span><span class="token string">'CreateListFromArrayLike called on non-object'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> thisArg <span class="token operator">===</span> <span class="token string">'undefined'</span> <span class="token operator">||</span> thisArg <span class="token operator">===</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        thisArg <span class="token operator">=</span> <span class="token function">getGlobalObject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    thisArg <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> __fn <span class="token operator">=</span> <span class="token string">'__'</span> <span class="token operator">+</span> <span class="token keyword">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getTime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> originalVal <span class="token operator">=</span> thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> hasOriginalVal <span class="token operator">=</span> thisArg<span class="token punctuation">.</span><span class="token function">hasOwnProperty</span><span class="token punctuation">(</span>__fn<span class="token punctuation">)</span><span class="token punctuation">;</span>
    thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> code <span class="token operator">=</span> <span class="token function">generateFunctionCode</span><span class="token punctuation">(</span>argsArray<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> result <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">Function</span><span class="token punctuation">(</span>code<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">,</span> __fn<span class="token punctuation">,</span> argsArray<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">delete</span> thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">if</span><span class="token punctuation">(</span>hasOriginalVal<span class="token punctuation">)</span><span class="token punctuation">{</span>
        thisArg<span class="token punctuation">[</span>__fn<span class="token punctuation">]</span> <span class="token operator">=</span> originalVal<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token class-name">Function</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">callFn</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token function">call</span><span class="token punctuation">(</span><span class="token parameter">thisArg</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">var</span> argsArray <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token keyword">var</span> argumentsLength <span class="token operator">=</span> arguments<span class="token punctuation">.</span>length<span class="token punctuation">;</span>
    <span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> i <span class="token operator">&lt;</span> argumentsLength <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
        argsArray<span class="token punctuation">[</span>i<span class="token punctuation">]</span> <span class="token operator">=</span> arguments<span class="token punctuation">[</span>i <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">applyFn</span><span class="token punctuation">(</span>thisArg<span class="token punctuation">,</span> argsArray<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="扩展阅读"><a href="#扩展阅读" class="header-anchor">#</a> 扩展阅读</h2> <p><a href="http://www.ituring.com.cn/book/tupubarticle/7768" target="_blank" rel="noopener noreferrer">《JavaScript设计模式与开发实践》- 第二章 第 2 章　this、call和apply<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br> <a href="https://cloud.tencent.com/developer/article/1023535" target="_blank" rel="noopener noreferrer">JS魔法堂：再次认识Function.prototype.call<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br> <a href="https://github.com/jawil/blog/issues/16" target="_blank" rel="noopener noreferrer">不用call和apply方法模拟实现ES5的bind方法<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br> <a href="https://juejin.im/post/5907eb99570c3500582ca23c" target="_blank" rel="noopener noreferrer">JavaScript深入之call和apply的模拟实现<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br></p> <h2 id="关于"><a href="#关于" class="header-anchor">#</a> 关于</h2> <p>作者：常以<strong>若川</strong>为名混迹于江湖。前端路上 | PPT爱好者 | 所知甚少，唯善学。<br> <a href="https://lxchuan12.github.io/" target="_blank" rel="noopener noreferrer">个人博客<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a><br> <a href="https://juejin.im/user/1415826704971918/posts" target="_blank" rel="noopener noreferrer">掘金专栏<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，欢迎关注~<br> <a href="https://segmentfault.com/blog/lxchuan12" target="_blank" rel="noopener noreferrer"><code>segmentfault</code>前端视野专栏<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，开通了<strong>前端视野</strong>专栏，欢迎关注~<br> <a href="https://zhuanlan.zhihu.com/lxchuan12" target="_blank" rel="noopener noreferrer">知乎前端视野专栏<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，开通了<strong>前端视野</strong>专栏，欢迎关注~<br> <a href="https://github.com/lxchuan12/blog" target="_blank" rel="noopener noreferrer">github blog<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>，相关源码和资源都放在这里，求个<code>star</code>^_^~</p> <h2 id="微信公众号-若川视野"><a href="#微信公众号-若川视野" class="header-anchor">#</a> 微信公众号  若川视野</h2> <p>可能比较有趣的微信公众号，长按扫码关注。也可以加微信 <code>ruochuan12</code>，注明来源，拉您进【前端视野交流群】。</p> <p><img src="/assets/img/wechat-official-accounts-mini.d9491f62.png" alt="若川视野"></p></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">最后更新时间:</span> <span class="time">4/4/2021, 3:33:55 AM</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/js-this/" class="prev">
        面试官问：JS的this指向
      </a></span> <span class="next"><a href="/js-implement-bind/">
        面试官问：能否模拟实现JS的bind方法
      </a>
      →
    </span></p></div> </main></div><div class="global-ui"><BackToTop></BackToTop><!----></div></div>
    <script src="/assets/js/app.9fbcafa6.js" defer></script><script src="/assets/js/2.33539d56.js" defer></script><script src="/assets/js/36.21f88fe5.js" defer></script><script src="/assets/js/23.72249401.js" defer></script>
  </body>
</html>
